<html>
<head><meta charset="utf-8"><title>for loops &amp; ? operator · t-compiler/rust-analyzer · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/index.html">t-compiler/rust-analyzer</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html">for loops &amp; ? operator</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="168751523"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/168751523" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#168751523">(Jun 22 2019 at 13:34)</a>:</h4>
<p>I added issues with hopefully adequate mentoring instructions for <a href="https://github.com/rust-analyzer/rust-analyzer/issues/1425" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/issues/1425">for loops</a> and the <a href="https://github.com/rust-analyzer/rust-analyzer/issues/1426" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/issues/1426">? operator</a>. I guess this would be a good place for questions (and/or disagreements about handling them directly instead of desugaring) ;)</p>



<a name="168751731"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/168751731" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#168751731">(Jun 22 2019 at 13:41)</a>:</h4>
<p>I'd like to go via desugaring, but <em>not</em> as the initial implementation. Desugaring is tricky for IDEs, so it makes sense to experiment with it more.</p>



<a name="168752143"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/168752143" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#168752143">(Jun 22 2019 at 13:55)</a>:</h4>
<p>Yeah. In any case, I think everything we need to build for the 'handling it directly' approach we would also need for the desugaring approach.</p>



<a name="168752438"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/168752438" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#168752438">(Jun 22 2019 at 14:05)</a>:</h4>
<p>That's true, and, for desugaring, I think it maybe makes sense to to a bit of up-front design of the hir::Body, scopes and source maps. I feel like the current incarnation is not the best one: in particular, it seems like we should name-resolve expressions when lowering to the <code>Body</code>.</p>



<a name="169097780"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/169097780" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> levi <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#169097780">(Jun 27 2019 at 02:08)</a>:</h4>
<p>i know someone has already taken this on github - but i was giving this a stab on sunday and got stuck at <code>resolve_obligations_as_possible</code> on the line <code>let (solution, canonicalized) = match &amp;obligation</code> where the compiler keeps on not allowing me to have a generic over Canonicalized&lt;T&gt;. if i could get past that (or if zbelial solves it) - imight be able to work on the ? inference</p>



<a name="169127129"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/169127129" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#169127129">(Jun 27 2019 at 11:55)</a>:</h4>
<p><span class="user-mention" data-user-id="217399">@levi</span> could you push your in-progress branch somewhere? It would be easier to see the problem that way.</p>



<a name="169128202"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/169128202" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> levi <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#169128202">(Jun 27 2019 at 12:09)</a>:</h4>
<p><a href="https://github.com/urbandove/rust-analyzer/tree/for-loops" target="_blank" title="https://github.com/urbandove/rust-analyzer/tree/for-loops">https://github.com/urbandove/rust-analyzer/tree/for-loops</a> currently - i think im supposed to add a trait - but i couldnt get that wokring</p>



<a name="169128705"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/169128705" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#169128705">(Jun 27 2019 at 12:16)</a>:</h4>
<p>So, that's the limitation of Rust: you have match arms of different types, and in Rust, unlike something Java, you can't unify those to a super-type</p>



<a name="169128739"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/169128739" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#169128739">(Jun 27 2019 at 12:17)</a>:</h4>
<p>The simplest fix would be to just pull the code <em>after</em> the match branch inside:</p>
<div class="codehilite"><pre><span></span>    fn resolve_obligations_as_possible(&amp;mut self) {
        let obligations = mem::replace(&amp;mut self.obligations, Vec::new());
        for obligation in obligations {
            match &amp;obligation {
                Obligation::Trait(tr) =&gt; {
                    let canonicalized = self.canonicalizer().canonicalize_trait_ref(tr.clone());
                    let (solution, canonicalized) = (
                        self.db.implements(
                            self.resolver.krate().unwrap(),
                            canonicalized.value.clone(),
                        ),
                        canonicalized,
                    );
                    match solution {
                        Some(Solution::Unique(substs)) =&gt; {
                            canonicalized.apply_solution(self, substs.0);
                        }
                        Some(Solution::Ambig(Guidance::Definite(substs))) =&gt; {
                            canonicalized.apply_solution(self, substs.0);
                            self.obligations.push(obligation);
                        }
                        Some(_) =&gt; {
                            // FIXME use this when trying to resolve everything at the end
                            self.obligations.push(obligation);
                        }
                        None =&gt; {
                            // FIXME obligation cannot be fulfilled =&gt; diagnostic
                        }
                    }
                }
                Obligation::Projection(pr) =&gt; {
                    let canonicalized = self.canonicalizer().canonicalize_projection(pr.clone());
                    let (solution, canonicalized) = (
                        self.db
                            .normalize(self.resolver.krate().unwrap(), canonicalized.value.clone()),
                        canonicalized,
                    );
                    match solution {
                        Some(Solution::Unique(substs)) =&gt; {
                            canonicalized.apply_solution(self, substs.0);
                        }
                        Some(Solution::Ambig(Guidance::Definite(substs))) =&gt; {
                            canonicalized.apply_solution(self, substs.0);
                            self.obligations.push(obligation);
                        }
                        Some(_) =&gt; {
                            // FIXME use this when trying to resolve everything at the end
                            self.obligations.push(obligation);
                        }
                        None =&gt; {
                            // FIXME obligation cannot be fulfilled =&gt; diagnostic
                        }
                    }
                }
            };
        }
    }
</pre></div>



<a name="169128761"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/169128761" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#169128761">(Jun 27 2019 at 12:17)</a>:</h4>
<p>The duplicated part can be extracted into a generic function to make this nicer</p>



<a name="169128826"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/169128826" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#169128826">(Jun 27 2019 at 12:18)</a>:</h4>
<p>I am not sure if that is the right code to begin with, I am not really proficient with chalk, but that at lest fixes the compilation error :D</p>



<a name="169128835"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/169128835" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#169128835">(Jun 27 2019 at 12:18)</a>:</h4>
<p><span class="user-mention" data-user-id="217399">@levi</span> does that help?</p>



<a name="169137426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/169137426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#169137426">(Jun 27 2019 at 14:03)</a>:</h4>
<p>another possibility might be canonicalizing the whole <code>Obligation</code> <span aria-label="thinking" class="emoji emoji-1f914" role="img" title="thinking">:thinking:</span>  in addition to <code>canonicalize_trait_ref</code> and <code>canonicalize_projection</code>, you'd have <code>canonicalize_obligation</code>, and you'd call that before the match and then do the match on the canonicalized obligation, and the rest could be generic again (I think)</p>



<a name="169141884"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/for%20loops%20%26%20%3F%20operator/near/169141884" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> levi <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/for.20loops.20.26.20.3F.20operator.html#169141884">(Jun 27 2019 at 14:52)</a>:</h4>
<p>i was thinking about that - it just looked overly verbose to me - and though there was an easier way.<br>
ill try that later today and see how it goes. and maybe after if i get that working i can have a look at trying what <span class="user-mention" data-user-id="129457">@Florian Diebold</span> suggested</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>